/**
 * X.U.E frameworks
 * X : xue	学而思基础库
 * U : UI	学而思UI库
 * E : extend	学而思扩展
 * Copyright 2012 Xueersi Inc. All rights reserved.
 */



/**
 * @namespace xue.cookie 操作cookie的方法。
 */
xue.cookie = xue.cookie || {};
/**
 * 验证字符串是否合法的cookie键名
 * 
 * @param {string} key 需要遍历的数组
 * @meta standard
 * @return {boolean} 是否合法的cookie键名
 */
xue.cookie._isValid = function (key) {
    // http://www.w3.org/Protocols/rfc2109/rfc2109
    // Syntax:  General
    // The two state management headers, Set-Cookie and Cookie, have common
    // syntactic properties involving attribute-value pairs.  The following
    // grammar uses the notation, and tokens DIGIT (decimal digits) and
    // token (informally, a sequence of non-special, non-white space
    // characters) from the HTTP/1.1 specification [RFC 2068] to describe
    // their syntax.
    // av-pairs   = av-pair *(";" av-pair)
    // av-pair    = attr ["=" value] ; optional value
    // attr       = token
    // value      = word
    // word       = token | quoted-string
    
    // http://www.ietf.org/rfc/rfc2068.txt
    // token      = 1*<any CHAR except CTLs or tspecials>
    // CHAR       = <any US-ASCII character (octets 0 - 127)>
    // CTL        = <any US-ASCII control character
    //              (octets 0 - 31) and DEL (127)>
    // tspecials  = "(" | ")" | "<" | ">" | "@"
    //              | "," | ";" | ":" | "\" | <">
    //              | "/" | "[" | "]" | "?" | "="
    //              | "{" | "}" | SP | HT
    // SP         = <US-ASCII SP, space (32)>
    // HT         = <US-ASCII HT, horizontal-tab (9)>
        
    return (new RegExp("^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+\x24")).test(key);
};
(function(){
	var _c = xue.cookie, _d = document,	_v = _c._isValid;
		
	/**
	 * 获取cookie的值，不对值进行解码
	 * @name xue.cookie.getRaw
	 * @function
	 * @grammar xue.cookie.getRaw(key)
	 * @param {string} key 需要获取Cookie的键名      
	 * @returns {string|null} 获取的Cookie值，获取不到时返回null
	 */
	_c.getRaw = function (key) {
	    if (_v(key)) {
	        var reg = new RegExp("(^| )" + key + "=([^;]*)(;|\x24)"),
	            result = reg.exec(_d.cookie);
	        if (result) {
	            return result[2] || null;
	        }
	    }
	    return null;
	};
	
	/**
	 * 获取cookie的值，用decodeURIComponent进行解码
	 * @name xue.cookie.get
	 * @function
	 * @grammar xue.cookie.get(key)
	 * @param {string} key 需要获取Cookie的键名
	 * @remark 该方法会对cookie值进行decodeURIComponent解码。如果想获得cookie源字符串，请使用getRaw方法。       
	 * @returns {string|null} cookie的值，获取不到时返回null
	 */
	_c.get = function (key) {
	    var value = _c.getRaw(key);
	    if ('string' == typeof value) {
	        value = decodeURIComponent(value);
	        return value;
	    }
	    return null;
	};
	
	/**
	 * 设置cookie的值，不对值进行编码
	 * @name xue.cookie.setRaw
	 * @function
	 * @grammar xue.cookie.setRaw(key, value[, options])
	 * @param {string} key 需要设置Cookie的键名
	 * @param {string} value 需要设置Cookie的值
	 * @param {Object} [options] 设置Cookie的其他可选参数 options参数包括：
	 * 		options = {
	 * 			path 	: '',			// {string} 		[path] 		cookie路径
	 * 			expires	: 2011-12-12,	// {Date|number} 	[expires] 	cookie过期时间,如果类型是数字的话, 单位是毫秒
	 * 			domain	: '',			// {string} 		[domain] 	cookie域名
	 * 			secure	: ''			// {string} 		[secure] 	cookie是否安全传输
	 * 		};
	 */
	_c.setRaw = function (key, value, options) {
	    if (!_v(key)) {
	        return;
	    }
	    __o = options || {};

	    // 计算cookie过期时间
	    var expires = __o.expires;
	    if ('number' == typeof __o.expires) {
	        expires = new Date();
	        expires.setTime(expires.getTime() + __o.expires);
	    }
	    
	    _d.cookie =
	        key + "=" + value
	        + (__o.path ? "; path=" + __o.path : "")
	        + (expires ? "; expires=" + expires.toGMTString() : "")
	        + (__o.domain ? "; domain=" + __o.domain : "")
	        + (__o.secure ? "; secure" : ''); 
	};
	/**
	 * 设置cookie的值，用encodeURIComponent进行编码
	 * @name xue.cookie.set
	 * @function
	 * @grammar xue.cookie.set(key, value[, options])
	 * @param {string} key 需要设置Cookie的键名
	 * @param {string} value 需要设置Cookie的值
	 * @param {Object} [options] 设置Cookie的其他可选参数 options参数包括：
	 * 		options = {
	 * 			path 	: '',			// {string} 		[path] 		cookie路径
	 * 			expires	: 2011-12-12,	// {Date|number} 	[expires] 	cookie过期时间,如果类型是数字的话, 单位是毫秒
	 * 			domain	: '',			// {string} 		[domain] 	cookie域名
	 * 			secure	: ''			// {string} 		[secure] 	cookie是否安全传输
	 * 		};
	 * @remark 该方法会对cookie值进行encodeURIComponent编码。如果想设置cookie源字符串，请使用setRaw方法。

	 */
	_c.set = function (key, value, options) {
	    _c.setRaw(key, encodeURIComponent(value), options);
	};		
	/**
	 * 删除cookie的值
	 * @name xue.cookie.remove
	 * @function
	 * @grammar xue.cookie.remove(key, options)
	 * @param {string} key 需要删除Cookie的键名
	 * @param {Object} options 需要删除的cookie对应的 path domain 等值
	 */
	_c.remove = function (key, options) {
	    __o = options || {};
	    __o.expires = new Date(0);
	    _c.setRaw(key, '', __o);
	};
})();


